package api

import (
	"strconv"

	"github.com/gin-gonic/gin"

	tagApp "BookStack/internal/application/tag"
	"BookStack/internal/interfaces/middleware"
	"BookStack/internal/interfaces/presenter"
)

// TagHandler 标签API处理器
type TagHandler struct {
	tagService tagApp.Service
	response   presenter.ResponseFormatter
}

// NewTagHandler 创建标签API处理器
func NewTagHandler(tagService tagApp.Service) *TagHandler {
	return &TagHandler{
		tagService: tagService,
		response:   presenter.NewResponseFormatter(),
	}
}

// RegisterRoutes 注册路由
func (h *TagHandler) RegisterRoutes(r *gin.RouterGroup) {
	// 公开接口
	public := r.Group("/tag")
	{
		public.GET("/list", h.ListTags)
		public.GET("", h.GetTag) // 支持通过id或slug参数获取标签
		public.GET("/hot", h.GetHotTags)
	}

	// 管理员接口
	admin := r.Group("/admin/tag")
	admin.Use(middleware.JWTAuth(), middleware.AdminAuth()) // 管理员权限认证中间件
	{
		admin.GET("/list", h.ListTags) // 管理员获取标签列表
		admin.POST("", h.CreateTag)
		admin.PUT("", h.UpdateTag)
		admin.DELETE("", h.DeleteTag)
		admin.DELETE("/batch-delete", h.BatchDeleteTags)
		admin.GET("/:id/stats", h.GetTagStat)
	}
}

// ListTags 获取标签列表
// @Summary 获取标签列表
// @Description 获取所有标签列表
// @Tags 标签
// @Accept json
// @Produce json
// @Param page query int false "页码，默认为1"
// @Param page_size query int false "每页数量，默认为20，最大100"
// @Param type query int false "标签类型（1：文章标签，2：书籍标签）"
// @Success 200 {object} presenter.Response{data=tag.TagListResponse}
// @Router /api/v1/tag/list [get]
func (h *TagHandler) ListTags(c *gin.Context) {
	var params tagApp.TagListQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 {
		params.PageSize = 10
	} else if params.PageSize > 100 {
		params.PageSize = 100
	}

	result, err := h.tagService.ListTags(c.Request.Context(), &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}

// GetTag 获取标签详情
// @Summary 获取标签详情
// @Description 获取指定ID或Slug的标签详情
// @Tags 标签
// @Accept json
// @Produce json
// @Param id query string false "标签ID"
// @Param slug query string false "标签别名"
// @Success 200 {object} presenter.Response{data=tag.TagResponse}
// @Router /api/v1/tag [get]
func (h *TagHandler) GetTag(c *gin.Context) {
	// 优先通过ID查询
	idStr := c.Query("id")
	if idStr != "" {
		id, err := strconv.ParseUint(idStr, 10, 32)
		if err != nil {
			c.Error(tagApp.ValidationError("id", "无效的标签ID"))
			return
		}

		tag, err := h.tagService.GetTag(c.Request.Context(), uint(id))
		if err != nil {
			c.Error(err)
			return
		}

		h.response.Success(c, tag)
		return
	}

	// 通过Slug查询
	slug := c.Query("slug")
	if slug != "" {
		tag, err := h.tagService.GetTagBySlug(c.Request.Context(), slug)
		if err != nil {
			c.Error(err)
			return
		}

		h.response.Success(c, tag)
		return
	}

	c.Error(tagApp.ValidationError("", "必须提供id或slug参数"))
}

// GetHotTags 获取热门标签
// @Summary 获取热门标签
// @Description 获取使用次数最多的热门标签
// @Tags 标签
// @Accept json
// @Produce json
// @Param type query int false "标签类型（1：文章标签，2：书籍标签）"
// @Param limit query int false "返回数量，默认为10，最大100"
// @Success 200 {object} presenter.Response{data=[]tag.TagResponse}
// @Router /api/v1/tag/hot [get]
func (h *TagHandler) GetHotTags(c *gin.Context) {
	var tagType *int
	typeStr := c.Query("type")
	if typeStr != "" {
		t, err := strconv.Atoi(typeStr)
		if err != nil {
			c.Error(tagApp.ValidationError("type", "无效的标签类型"))
			return
		}
		tagType = &t
	}

	limitStr := c.DefaultQuery("limit", "10")
	limit, err := strconv.Atoi(limitStr)
	if err != nil {
		limit = 10
	}

	tags, err := h.tagService.GetHotTags(c.Request.Context(), tagType, limit)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, tags)
}

// CreateTag 创建标签
// @Summary 创建标签
// @Description 创建新标签
// @Tags 标签
// @Accept json
// @Produce json
// @Param tag body tag.CreateTagRequest true "标签信息"
// @Success 200 {object} presenter.Response{data=tag.TagResponse}
// @Router /api/v1/admin/tag [post]
func (h *TagHandler) CreateTag(c *gin.Context) {
	var req tagApp.CreateTagRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	tag, err := h.tagService.CreateTag(c.Request.Context(), &req)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, tag)
}

// UpdateTag 更新标签
// @Summary 更新标签
// @Description 更新标签信息
// @Tags 标签
// @Accept json
// @Produce json
// @Param tag body tag.UpdateTagRequest true "标签信息"
// @Success 200 {object} presenter.Response{data=tag.TagResponse}
// @Router /api/v1/admin/tag [put]
func (h *TagHandler) UpdateTag(c *gin.Context) {
	var req tagApp.UpdateTagRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	tag, err := h.tagService.UpdateTag(c.Request.Context(), &req)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, tag)
}

// DeleteTag 删除标签
// @Summary 删除标签
// @Description 删除指定ID的标签
// @Tags 标签
// @Accept json
// @Produce json
// @Param tag body object true "标签ID"
// @Success 200 {object} presenter.Response
// @Router /api/v1/admin/tag [delete]
func (h *TagHandler) DeleteTag(c *gin.Context) {
	var req struct {
		ID uint `json:"id" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	if err := h.tagService.DeleteTag(c.Request.Context(), req.ID); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// BatchDeleteTags 批量删除标签
// @Summary 批量删除标签
// @Description 批量删除多个标签
// @Tags 标签
// @Accept json
// @Produce json
// @Param ids body []int true "标签ID列表"
// @Success 200 {object} presenter.Response
// @Router /api/v1/admin/tag/batch-delete [delete]
func (h *TagHandler) BatchDeleteTags(c *gin.Context) {
	var req struct {
		IDs []uint `json:"ids" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	if len(req.IDs) == 0 {
		c.Error(tagApp.ValidationError("ids", "标签ID列表不能为空"))
		return
	}

	if err := h.tagService.BatchDeleteTags(c.Request.Context(), req.IDs); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// GetTagStat 获取标签使用统计
// @Summary 获取标签使用统计
// @Description 获取标签在文章和书籍中的使用统计
// @Tags 标签
// @Accept json
// @Produce json
// @Param id path int true "标签ID"
// @Success 200 {object} presenter.Response{data=tag.TagStatResponse}
// @Router /api/v1/admin/tag/{id}/stats [get]
func (h *TagHandler) GetTagStat(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.Error(tagApp.ValidationError("id", "无效的标签ID"))
		return
	}

	stat, err := h.tagService.GetTagStat(c.Request.Context(), uint(id))
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, stat)
}
